package com.iotechn.unimall.biz.service.integral;


import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.iotechn.unimall.core.Const;
import com.iotechn.unimall.data.component.CacheComponent;
import com.iotechn.unimall.data.domain.*;
import com.iotechn.unimall.data.enums.IntegralSonType;
import com.iotechn.unimall.data.enums.IntegralType;
import com.iotechn.unimall.data.enums.SystemStatusType;
import com.iotechn.unimall.data.mapper.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class IntegralBizService {
    private static final String CA_INTEGRALTASK_DTO_KEY = "CA_INTEGRALTASK_DTO_KEY";
    private static final Logger logger = LoggerFactory.getLogger(IntegralBizService.class);
    @Autowired
    private UserIntegralSigninMapper userIntegralSigninMapper;
    @Autowired
    private IntegralUserMapper integralUserMapper;
    @Autowired
    private IntegralTaskMapper integralTaskMapper;
    @Autowired
    private IntegralDetailMapper integralDetailMapper;

    @Autowired
    private RewardLadderMapper rewardLadderMapper;

    @Autowired
    private InviteLogMapper inviteLogMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private CacheComponent cacheComponent;
    /**
     * 初始化任务信息
     * 初始化团长等级自动升级缓存
     */
    @PostConstruct
    private void initConfig() throws Exception {
        //初始化团长
        this.initIntegralTask();

    }

    // @Transactional(rollbackFor = Exception.class)
    public List<IntegralTaskDO> initIntegralTask() {
        cacheComponent.del(CA_INTEGRALTASK_DTO_KEY);
        List<IntegralTaskDO> integralTaskDOS = integralTaskMapper.selectList(new EntityWrapper<IntegralTaskDO>()
        .setSqlSelect("ifnull(integral,0) as integral","type","ifnull(integral_title,'') as integralTitle",
        "ifnull(integral_desc,'') as integralDesc","ifnull(icon,'') as icon","status","id"));
//初始化
        cacheComponent.putObj(CA_INTEGRALTASK_DTO_KEY, integralTaskDOS, Const.CACHE_ONE_DAY);
        logger.info("[初始化积分任务]:{}个", integralTaskDOS.size());
        return integralTaskDOS;
    }

    public boolean addIntegralDetailAdd(Long userId, Integer type, Integer sonType, Long typeId,String detail) {
        return this.insertIntegralDetailAdd(userId, type, sonType, typeId, 0,detail);
    }

    /**
     * 外层加事务
     * 减少积分
     *
     * @param userId  用户id
     * @param type    大类
     * @param sonType 小分类
     * @param typeId  当前id
     * @return
     */
    public boolean insertIntegralDetailAdd(Long userId, Integer type, Integer sonType, Long typeId, Integer money,String detail) {
        IntegralUserDO integralUserDO = new IntegralUserDO();
        integralUserDO.setUserId(userId);
        integralUserDO = integralUserMapper.selectOne(integralUserDO);
        if (integralUserDO == null) {
            integralUserDO = new IntegralUserDO();
            integralUserDO.setUserId(userId);
            integralUserDO.setTotalIntegral(0);
            integralUserDO.setCurrentIntegral(0);
            integralUserMapper.insert(integralUserDO);
        }
        IntegralTaskDO integralTaskDO = null;//integralTaskMapper.selectById(sonType);
        List<IntegralTaskDO> initIntegralTask = cacheComponent.getObjList(CA_INTEGRALTASK_DTO_KEY, IntegralTaskDO.class);
        if(initIntegralTask == null || initIntegralTask.size() < 1){
            initIntegralTask= integralTaskMapper.selectList(new EntityWrapper<IntegralTaskDO>()
                    .setSqlSelect("ifnull(integral,0) as integral","type","ifnull(integral_title,'') as integralTitle",
                            "ifnull(integral_desc,'') as integralDesc","ifnull(icon,'') as icon","status","id"));
            cacheComponent.putObj(CA_INTEGRALTASK_DTO_KEY, initIntegralTask, Const.CACHE_ONE_DAY);
        }
        for (IntegralTaskDO integralTaskDO1 : initIntegralTask) {
            if (integralTaskDO1 != null && integralTaskDO1.getId().intValue() == sonType.intValue()) {
                integralTaskDO = integralTaskDO1;
                break;
            }
        }
        if (integralTaskDO == null) {
            return false;
        }
        int integral = 0;
        if (integralTaskDO.getType().intValue() == 1) {
            List<RewardLadderDO> rewardLadderDOS = rewardLadderMapper.selectList(new EntityWrapper<RewardLadderDO>().eq("type", integralTaskDO.getId()).eq("status", SystemStatusType.ON.getCode()));
            Map<Integer, RewardLadderDO> rewardLadderMap = rewardLadderDOS.stream().collect(Collectors.toMap(RewardLadderDO::getImplementTimes, Function.identity(), (key1, key2) -> key2));


            integral = integralTaskDO.getIntegral();
        } else {
            //一元钱换多少积分 按比例来的
            integral = (integralTaskDO.getIntegral() * money / 100);
        }
        //给用户增加积分
        integralUserMapper.incIntegral(userId, integral);
        //给用户增加积分记录
        IntegralDetailDO integralDetailDO = new IntegralDetailDO();
        integralDetailDO.setPreIntegral(integralUserDO.getCurrentIntegral());
        integralDetailDO.setCurrentIntegral(integralUserDO.getCurrentIntegral() + integral);
        integralDetailDO.setChangeIntegral(integral);
        integralDetailDO.setIntegralTime(new Date());
        integralDetailDO.setType(type);
        integralDetailDO.setSonType(sonType);
        integralDetailDO.setGmtCreate(new Date());
        integralDetailDO.setGmtUpdate(new Date());
        integralDetailDO.setUserId(userId);
        integralDetailDO.setTypeId(typeId);
        integralDetailDO.setDetail(detail);
        integralDetailMapper.insert(integralDetailDO);
        return true;
    }

    /**
     * 外层加事务
     * 添加积分
     *
     * @param integralUserDO 用户信息
     * @param type           大类
     * @param sonType        小分类
     * @param typeId         当前id
     * @return
     */
    public boolean decIntegralDetail(IntegralGoodsDO integralGoodsDO, IntegralUserDO integralUserDO, Integer type, Integer sonType, Long typeId,String title) {
        //给用户减少积分
        integralUserMapper.decIntegral(integralUserDO.getUserId(),integralGoodsDO.getIntegral());
        //给用户增加积分记录
        IntegralDetailDO integralDetailDO=new IntegralDetailDO();
        integralDetailDO.setPreIntegral(integralUserDO.getCurrentIntegral());
        integralDetailDO.setCurrentIntegral(integralUserDO.getCurrentIntegral()-integralGoodsDO.getIntegral());
        integralDetailDO.setChangeIntegral(integralGoodsDO.getIntegral());
        integralDetailDO.setIntegralTime(new Date());
        integralDetailDO.setType(type);
        integralDetailDO.setDetail(title);
        integralDetailDO.setSonType(sonType);
        integralDetailDO.setGmtCreate(new  Date());
        integralDetailDO.setIgoodsId(integralGoodsDO.getId());
        integralDetailDO.setGmtUpdate(new Date());
        integralDetailDO.setUserId(integralUserDO.getUserId());
        integralDetailDO.setTypeId(typeId);
        integralDetailMapper.insert(integralDetailDO);
        return true;
    }

    /**
     * 减少积分
     * 添加积分
     * @param integralUserDO 用户信息
     * @param type  大类
     * @param sonType 小分类
     * @param typeId  当前id
     * @return
     */
    public boolean decIntegralDetail(Integer integral, Integer money, IntegralUserDO integralUserDO, Integer type, Integer sonType, Long typeId,String title) {
        //给用户减少积分
        integralUserMapper.decIntegral(integralUserDO.getUserId(),integral);
        //给用户增加积分记录
        IntegralDetailDO integralDetailDO=new IntegralDetailDO();
        integralDetailDO.setPreIntegral(integralUserDO.getCurrentIntegral());
        integralDetailDO.setAmount(money);
        integralDetailDO.setDetail(title);
        integralDetailDO.setCurrentIntegral(integralUserDO.getCurrentIntegral()-integral);
        integralDetailDO.setChangeIntegral(integral);
        integralDetailDO.setIntegralTime(new Date());
        integralDetailDO.setType(type);
        integralDetailDO.setSonType(sonType);
        integralDetailDO.setGmtCreate(new  Date());
        integralDetailDO.setGmtUpdate(new Date());
        integralDetailDO.setUserId(integralUserDO.getUserId());
        integralDetailDO.setTypeId(typeId);
        integralDetailMapper.insert(integralDetailDO);
        return true;
    }

    /**
     * 添加积分
     * @param userId  用户id
     * @param integral 积分额
     * @param sonType  操作子类型
     * @param jobId    任务主键
     */
    public void addIntegral(Long userId,Integer integral,Integer sonType,String typeDetail,Long jobId){
        IntegralUserDO integralUserOrig= new IntegralUserDO();
        List<IntegralUserDO> integralUserDOS = integralUserMapper.selectList(new EntityWrapper<IntegralUserDO>().eq("user_id", userId));
        if(integralUserDOS == null || integralUserDOS.size() < 1){
            integralUserOrig = insertIntegralUser(userId);
        }
        if(integralUserDOS != null && integralUserDOS.size() > 0){
            integralUserOrig = integralUserDOS.get(0);
        }
        //给用户增加积分
        integralUserMapper.incIntegral(userId, integral);
        //给用户增加积分记录
        IntegralDetailDO integralDetailDO = new IntegralDetailDO();
        integralDetailDO.setPreIntegral(integralUserOrig.getCurrentIntegral());
        integralDetailDO.setCurrentIntegral(integralUserOrig.getCurrentIntegral() + integral);
        integralDetailDO.setChangeIntegral(integral);
        integralDetailDO.setIntegralTime(new Date());
        integralDetailDO.setType(IntegralType.EARN.getCode());
        integralDetailDO.setDetail(typeDetail);
        integralDetailDO.setSonType(sonType);
        integralDetailDO.setGmtCreate(new Date());
        integralDetailDO.setGmtUpdate(new Date());
        integralDetailDO.setUserId(userId);
        integralDetailDO.setTypeId(jobId);
        integralDetailMapper.insert(integralDetailDO);
    }

    /**
     *  计算签到任务获得的积分  (可计算奖励阶梯)
     * @return
     */
    public Integer calculateSignIntegral(Long userId,Integer currsignTimes) {
        //获取任务 获取积分
        IntegralTaskDO integralTaskDO=integralTaskMapper.selectById(IntegralSonType.SIGN.getCode());
        //判断阶梯 获取积分
        List<RewardLadderDO> rewardLadderDOS = rewardLadderMapper.selectList(new EntityWrapper<RewardLadderDO>().eq("type", integralTaskDO.getId()).eq("status", SystemStatusType.ON.getCode()));
        Map<Integer, RewardLadderDO> rewardLadderMap = rewardLadderDOS.stream().collect(Collectors.toMap(RewardLadderDO::getImplementTimes, Function.identity(), (key1, key2) -> key2));
        int reward = 0;
        if(rewardLadderMap != null){
            RewardLadderDO rewardLadderDO = rewardLadderMap.get(currsignTimes);
            if(rewardLadderDO != null){
                reward= rewardLadderDO.getIntegral();
            }
        }
        //计算最后积分
        int signIntegral = integralTaskDO.getIntegral() + reward;
        return signIntegral;
    }

    /**
     * 修改用户签到总次数
     * @param userId
     * @param signintimes
     */
    public void computeSignTimes(Long userId,Integer signintimes){
        IntegralUserDO integralUserDO = new IntegralUserDO();
        integralUserDO.setUserId(userId);
        integralUserDO = integralUserMapper.selectOne(integralUserDO);
        integralUserDO.setSignintimes(signintimes);
        integralUserMapper.updateById(integralUserDO);
    }


    /**
     * 记录签到任务
     * @param userId
     */
    public Integer recordSign(Long userId,Integer signIntegral,Integer currsignTimes){
        Date now =new Date();
        //签到记录
        UserIntegralSigninDO userIntegralSigninDO =new UserIntegralSigninDO();
        userIntegralSigninDO.setAddIntegral(signIntegral);
        userIntegralSigninDO.setSigninTime(now);
        userIntegralSigninDO.setUserId(userId);
        userIntegralSigninDO.setAdminId(userId);
        userIntegralSigninDO.setGmtUpdate(now);
        userIntegralSigninDO.setGmtCreate(now);
        userIntegralSigninDO.setSignintimes(currsignTimes);
        return userIntegralSigninMapper.insert(userIntegralSigninDO);
    }

    /**
     * 邀请奖励 邀请人积分  （可计算奖励阶梯）
     * @param userId   发起邀请人
     * @return
     */
    public Integer calculateShareIntegral(Long userId,List<InviteLogDO> inviteeUsers) {
        //获取任务 获取积分
        IntegralTaskDO integralTaskDO=integralTaskMapper.selectById(IntegralSonType.INVITE.getCode());
        //判断阶梯 获取积分
        List<RewardLadderDO> rewardLadderDOS = rewardLadderMapper.selectList(new EntityWrapper<RewardLadderDO>().eq("type", integralTaskDO.getId()).eq("status", SystemStatusType.ON.getCode()));
        Map<Integer, RewardLadderDO> rewardLadderMap = rewardLadderDOS.stream().collect(Collectors.toMap(RewardLadderDO::getImplementTimes, Function.identity(), (key1, key2) -> key2));
        //邀请总人数
        int size = 0;
        if(inviteeUsers != null){
            size =  inviteeUsers.size();
        }
        int inviteNum = size + 1;
        int reward = 0;
        if(rewardLadderMap != null){
            RewardLadderDO rewardLadderDO = rewardLadderMap.get(inviteNum);
            if(rewardLadderDO != null){
                reward = rewardLadderDO.getIntegral();
            }
        }
        //计算最后积分
        int signIntegral = integralTaskDO.getIntegral() + reward;
        return signIntegral;
    }

    /**
     *   记录邀请任务
     * @param inviteUserId  邀请人
     * @param userId        被邀请人
     */
    public void recordShareAndRegist(Long inviteUserId,Long userId,Integer inviteIntegral){
        UserDO inviteUser = userMapper.selectById(inviteUserId);
        UserDO userDO = userMapper.selectById(userId);
        Date now=new Date();
        InviteLogDO inviteLogDO=new InviteLogDO();
        inviteLogDO.setGmtCreate(now);
        inviteLogDO.setGmtUpdate(now);
        inviteLogDO.setInviteeUserId(inviteUserId);
        inviteLogDO.setInviteesUserId(userId);
        inviteLogDO.setInviteePhone(inviteUser.getPhone());
        inviteLogDO.setInviteesPhone(userDO.getPhone());
        inviteLogDO.setInviteTime(now);
        inviteLogDO.setRegisterTime(now);
        inviteLogDO.setInviteStatus(SystemStatusType.ON.getCode());
        inviteLogDO.setInviteIntegral(inviteIntegral);
        inviteLogMapper.insert(inviteLogDO);
    }


    /**
     * 修改用户邀请总次数
     * @param userId
     * @param signintimes
     */
    public void computeShareTimes(Long userId,Integer shareTimes){
        IntegralUserDO integralUserDO = new IntegralUserDO();
        integralUserDO.setUserId(userId);
        integralUserDO = integralUserMapper.selectOne(integralUserDO);
        integralUserDO.setSharetimes(shareTimes);
        integralUserMapper.updateById(integralUserDO);
    }

    /**
     * 创建积分账户
     * @param userId
     */
    public IntegralUserDO insertIntegralUser(Long userId){
        Integer registIntegral = 0;
        IntegralTaskDO integralTaskDO = integralTaskMapper.selectById(IntegralSonType.REGIST.getCode());
        if(integralTaskDO != null){
            registIntegral = integralTaskDO.getIntegral();
        }
        Date now =new Date();
        IntegralUserDO integralUserDO = new IntegralUserDO();
        integralUserDO.setTotalIntegral(registIntegral);
        integralUserDO.setCurrentIntegral(registIntegral);
        integralUserDO.setIntegralTime(now);
        integralUserDO.setUserId(userId);
        integralUserDO.setAdminId(userId);
        integralUserDO.setGmtUpdate(now);
        integralUserDO.setGmtCreate(now);
        integralUserDO.setSignintimes(0);
        integralUserDO.setSharetimes(0);
        integralUserMapper.insert(integralUserDO);
        IntegralDetailDO integralDetailDO = new IntegralDetailDO();
        integralDetailDO.setPreIntegral(integralUserDO.getCurrentIntegral());
        integralDetailDO.setCurrentIntegral(integralUserDO.getCurrentIntegral());
        integralDetailDO.setChangeIntegral(registIntegral);
        integralDetailDO.setIntegralTime(new Date());
        integralDetailDO.setType(IntegralType.EARN.getCode());
        integralDetailDO.setSonType(IntegralSonType.REGIST.getCode());
        integralDetailDO.setDetail("新用户注册");
        integralDetailDO.setGmtCreate(new Date());
        integralDetailDO.setGmtUpdate(new Date());
        integralDetailDO.setUserId(userId);
        integralDetailDO.setTypeId(0L);
        integralDetailMapper.insert(integralDetailDO);
        return integralUserDO;
    }


    /**
     * 下单
     */
    public Integer takeOrderGetIntegral(OrderDO orderDO){
        IntegralTaskDO integralTaskDO = integralTaskMapper.selectById(IntegralSonType.FEE.getCode());
        if(orderDO.getActualPrice().intValue() != 0){
            return orderDO.getActualPrice() * integralTaskDO.getIntegral();
        }
        return 0;
    }

    /**
     * 充值
     */
    public Integer rechargeGetIntegral(RechargeableOrderDO rechargeableOrderDO){
        IntegralTaskDO integralTaskDO = integralTaskMapper.selectById(IntegralSonType.CHARGE.getCode());
        if(rechargeableOrderDO.getRechargePrice().intValue() != 0){
            return rechargeableOrderDO.getRechargePrice() * integralTaskDO.getIntegral();
        }
        return 0;
    }

    /**
     * 评论得积分
     * @return
     */
    public Integer appraiseGetIntegral(){
        IntegralTaskDO integralTaskDO = integralTaskMapper.selectById(IntegralSonType.COMMENT.getCode());
        return integralTaskDO.getIntegral();
    }
}

